import EventHelper from './EventHelper.js';

/**
 * 拖动移动
 * 
 * @param {HTMLElement} el 元素
 * @param {Object} options 配置项
 * @param {Number} options.threshold 移动阀值
 */
export default class GrabMove {

  static classType = 'GrabMove';
  get classType() {
    return GrabMove.classType;
  }

  _options = {
    threshold: 5,
  };
  constructor(el, options = {}) {
    if (!(el instanceof HTMLElement)) return;

    let self = this;
    self.el = el;
    Object.assign(self._options, options);
    let eventHelper = self.eventHelper = new EventHelper(el);

    eventHelper.on('mousedown', self._proxy('_start'));
    eventHelper.on('touchstart', self._proxy('_start'));
  }

  _proxy(name){
    let self = this;
    return function (e){
      return self[name](e);
    };
  }

  _start(startEvent){
    let self = this;
    let rect = self.el.getBoundingClientRect();
    self.start = {
      mx: startEvent.clientX,
      my: startEvent.clientY,
      x: parseInt(startEvent.clientX - rect.left),
      y: parseInt(startEvent.clientY - rect.top)
    };

    self.eventHelper.on('mousemove', self._proxy('_moving'));
    self.eventHelper.on('touchmove', self._proxy('_moving'));

    self.eventHelper.on('mouseup', self._proxy('_end'));
    self.eventHelper.on('touchend', self._proxy('_end'));

    if (self._options.onStart instanceof Function){
      self._options.onStart.call(self, startEvent);
    }

  }
  _moving(event){
    // 设置到元素上
    let self = this;

    if (!self._isMove(event)) return;


    self.el.style.right = null;
    self.el.style.bottom = null;
    self.el.style.left = event.clientX - self.start.x + 'px';
    self.el.style.top = event.clientY - self.start.y + 'px';

    if (self._options.onMove instanceof Function) {
      self._options.onMove.call(self, event);
    }
  }

  _end(event){
    let self = this;
    self.eventHelper.off('mousemove');
    self.eventHelper.off('touchmove');
    self.eventHelper.off('mouseup');
    self.eventHelper.off('touchend');

    if (self._options.onEnd instanceof Function) {
      self._options.onEnd.call(self, event);
    }
  }

  _isMove(event){
    let self = this;
    return Math.abs(self.start.mx - event.clientX) > self._options.threshold || Math.abs(self.start.my - event.clientY) > self._options.threshold;
  }

  destroy(){
    this.eventHelper.clear();
    this.el.style.right = null;
    this.el.style.bottom = null;
    this.el.style.left = null;
    this.el.style.top = null;
  }

}

